package com.example.redis.statemachine;

import com.example.redis.statemachine.aspect.ExecuteRes;
import com.example.redis.statemachine.consts.CommonConstants;
import com.example.redis.statemachine.enums.OrderStatusChangeEventEnum;
import com.example.redis.statemachine.enums.OrderStatusEnum;
import com.example.redis.statemachine.model.OrderDTO;
import com.example.redis.statemachine.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;

@Component
@WithStateMachine
@Transactional
@Slf4j
public class OrderStatusListener {

    //stateMachine无法抛出异常，异常会被状态机给消化掉
    //问题现象: 从orderStateMachine.sendEvent(message);获取的结果无法感知到。无论执行正常还是抛出异常，都返回true。

    @Resource
    private StateMachine<OrderStatusEnum, OrderStatusChangeEventEnum> orderStateMachine;

    //从WAIT_PAYMENT到WAIT_DELIVER
    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    @ExecuteRes(key = CommonConstants.PAY_TRANSITION)
    public void payTransition(Message<OrderStatusChangeEventEnum> message) {
        OrderDTO orderDTO = (OrderDTO) message.getHeaders().get(CommonConstants.ORDER_DTO);
        log.info("支付，状态机反馈信息：{}", message.getHeaders().toString());
        //更新订单
        orderDTO.setStatus(OrderStatusEnum.WAIT_DELIVER.getKey());
        //TODO 其他业务

        //模拟异常
        if (Objects.equals(orderDTO.getName(), "A")) {
            throw new RuntimeException("执行业务异常");
        }

    }

    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public void deliverTransition(Message<OrderStatusChangeEventEnum> message) {
        OrderDTO orderDTO = (OrderDTO) message.getHeaders().get(CommonConstants.ORDER_DTO);
        log.info("发货，状态机反馈信息：{}", message.getHeaders().toString());
        //更新订单
        orderDTO.setStatus(OrderStatusEnum.WAIT_RECEIVE.getKey());
        //TODO 其他业务
    }

    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public void receiveTransition(Message<OrderStatusChangeEventEnum> message) {
        OrderDTO orderDTO = (OrderDTO) message.getHeaders().get(CommonConstants.ORDER_DTO);
        log.info("确认收货，状态机反馈信息：{}", message.getHeaders().toString());
        //更新订单
        orderDTO.setStatus(OrderStatusEnum.FINISH.getKey());
        //TODO 其他业务
    }

}